package com.first.myvideo.video;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.BatteryManager;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

import com.first.myvideo.R;
import com.first.myvideo.dialog.BrightnessDialog;
import com.first.myvideo.dialog.LinePathDialog;
import com.first.myvideo.dialog.PositionDialog;
import com.first.myvideo.dialog.VolumeDialog;
import com.first.myvideo.minterface.MyVideoControlInterface;
import com.first.myvideo.minterface.PlayerStatus;

import java.util.Map;

/**
 * Created by Administrator on 2018/4/23.
 */

public class MyControl extends FrameLayout implements View.OnClickListener, SeekBar.OnSeekBarChangeListener, View.OnTouchListener {
    private View view;
    private ImageView control_loading_iv;
    private MyVideoControlInterface myVideoControlInterface;
    private ImageView control_title_back;
    private TextView control_title_tv;
    private ImageView control_title_battery;
    private ImageView control_start_btn;
    private SeekBar control_seekbar;
    private TextView control_time;
    private TextView control_line;
    private ImageView control_full;
    private LinearLayout control_loading_layout;
    private TextView control_loading_tv;
    private LinearLayout control_bottom_layout;
    private Handler upHandler = new Handler();
    private LinearLayout control_title_layout;
    private Map<String, String> linePathMap;
    private LinePathDialog linePathDialog;
    private float mDownX;
    private float mDownY;
    private boolean mNeedChangePosition = false;
    private boolean mNeedChangeVolume = false;
    private boolean mNeedChangeBrightness = false;

    private long mGestureDownPosition;
    private float mGestureDownBrightness;
    private int mGestureDownVolume;
    private long mNewPosition;
    private PositionDialog positionDialog;
    private BrightnessDialog brightnessDialog;
    private VolumeDialog volumeDialog;

    public MyControl(@NonNull Context context) {
        this(context, null, 0);
    }

    public MyControl(@NonNull Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyControl(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        view = LayoutInflater.from(context).inflate(R.layout.layout_control, null);
        LayoutParams lp = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        addView(view, lp);
        iniUI();
    }

    private void iniUI() {
        control_title_back = (ImageView) view.findViewById(R.id.control_title_back);
        control_start_btn = (ImageView) view.findViewById(R.id.control_start_btn);
        control_title_tv = (TextView) view.findViewById(R.id.control_title_tv);
        control_title_battery = (ImageView) view.findViewById(R.id.control_title_battery);
        control_title_battery.setVisibility(GONE);
        control_seekbar = (SeekBar) view.findViewById(R.id.control_seekbar);
        control_time = (TextView) view.findViewById(R.id.control_time);
        control_line = (TextView) view.findViewById(R.id.control_line);
        control_full = (ImageView) view.findViewById(R.id.control_full);
        control_loading_layout = (LinearLayout) view.findViewById(R.id.control_loading_layout);
        control_loading_tv = (TextView) view.findViewById(R.id.control_loading_tv);
        control_bottom_layout = (LinearLayout) view.findViewById(R.id.control_bottom_layout);
        control_title_layout = (LinearLayout) view.findViewById(R.id.control_title_layout);
        control_loading_iv=(ImageView)view.findViewById(R.id.control_loading_iv);

        setClick();
        iniData();
    }

    /**
     * 初始化动作
     */
    private void iniData() {
        invokeTopAndBottomLayout(true);
        positionDialog = new PositionDialog(getContext());
        brightnessDialog = new BrightnessDialog(getContext());
        volumeDialog = new VolumeDialog(getContext());
        Animation rotate = AnimationUtils.loadAnimation(getContext(), R.anim.progressbar_animo);
        control_loading_iv.startAnimation(rotate);
    }

    private void setClick() {
        control_title_back.setOnClickListener(this);
        control_start_btn.setOnClickListener(this);
        control_line.setOnClickListener(this);
        control_full.setOnClickListener(this);
        control_seekbar.setOnSeekBarChangeListener(this);
        this.setOnTouchListener(this);
        setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                invokeTopAndBottomLayout(!(control_bottom_layout.getVisibility() == VISIBLE));
                upHandler.removeCallbacks(topAndbottomRunable);
                upHandler.postDelayed(topAndbottomRunable, 2500);
            }
        });
    }

    @Override
    public void onClick(View view) {
        if (view.getId()==R.id.control_title_back){
            int currMode = myVideoControlInterface.currModeStatus();
            if (currMode == PlayerStatus.MODE_FULL_SCREEN) {
                //全屏状态下的返回
                myVideoControlInterface.exitFullScreen();
            } else if (currMode == PlayerStatus.MODE_NORMAL) {
                //正常状态下的返回
            }
        }else if (view.getId()==R.id.control_start_btn){
            if (myVideoControlInterface.isPlaying() || myVideoControlInterface.isBufferingPlaying() || myVideoControlInterface.isSeekToed()) {
                myVideoControlInterface.pause();
            } else if (myVideoControlInterface.isPaused() ||
                    myVideoControlInterface.isBufferingPaused() || myVideoControlInterface.isError()) {
                myVideoControlInterface.restart(false);
            } else if (myVideoControlInterface.isCompleted()) {
                myVideoControlInterface.restart(true);
            }
        }else if (view.getId()==R.id.control_line){
            if (null != linePathDialog) {
                linePathDialog.myshow();
                invokeTopAndBottomLayout(false);
            }
        }else if (view.getId()==R.id.control_full){
            int currPlayMode = myVideoControlInterface.currModeStatus();
            if (currPlayMode == PlayerStatus.MODE_FULL_SCREEN) {
                //全屏状态下
                myVideoControlInterface.exitFullScreen();//退出全屏
            } else if (currPlayMode == PlayerStatus.MODE_NORMAL) {
                //正常状态下
                myVideoControlInterface.enterFullScreen();//进入全屏
            }
        }
    }

    public void setMyVideoControlInterface(MyVideoControlInterface myVideoControlInterface) {
        this.myVideoControlInterface = myVideoControlInterface;
    }

    public void setTitle(String title) {
        control_title_tv.setText(title);
    }

    /**
     * 播放状态回调
     */
    public void onPlayStateChanged(int currStatus) {
        switch (currStatus) {
            case PlayerStatus.STATE_IDLE:
                //空闲状态
                control_loading_layout.setVisibility(GONE);
                break;
            case PlayerStatus.STATE_PREPARING:
                //准备中
                control_loading_layout.setVisibility(VISIBLE);
                control_loading_tv.setText("视频加载中...");
                break;
            case PlayerStatus.STATE_PREPARED:
                //准备完成
                control_loading_layout.setVisibility(GONE);
                control_start_btn.setImageResource(R.mipmap.icon_video_play);
                int currentPosition = myVideoControlInterface.getCurrentPosition();
                int duration = myVideoControlInterface.getDuration();
                control_time.setText(getTimeProgressFormat(currentPosition, duration));
                upHandler.removeCallbacks(topAndbottomRunable);
                invokeTopAndBottomLayout(true);
                break;
            case PlayerStatus.STATE_PLAYING:
                //播放中
                control_loading_layout.setVisibility(GONE);
                control_start_btn.setImageResource(R.mipmap.icon_video_pause);
                upHandler.post(upRunable);
                upHandler.post(topAndbottomRunable);
                break;
            case PlayerStatus.STATE_PAUSED:
                //暂停
                control_loading_layout.setVisibility(GONE);
                control_start_btn.setImageResource(R.mipmap.icon_video_play);
                upHandler.removeCallbacks(topAndbottomRunable);
                invokeTopAndBottomLayout(true);
                break;
            case PlayerStatus.STATE_BUFFERING_PLAYING:
                //播放状态下缓存
                control_loading_layout.setVisibility(VISIBLE);
                control_loading_tv.setText("视频缓存中...");
                control_start_btn.setImageResource(R.mipmap.icon_video_pause);
                break;
            case PlayerStatus.STATE_BUFFERING_PAUSED:
                //暂停状态下缓存
                control_loading_layout.setVisibility(VISIBLE);
                control_loading_tv.setText("视频缓存中...");
                control_start_btn.setImageResource(R.mipmap.icon_video_play);
                upHandler.removeCallbacks(topAndbottomRunable);
                invokeTopAndBottomLayout(true);
                break;
            case PlayerStatus.STATE_ERROR:
                //错误
                control_loading_layout.setVisibility(VISIBLE);
                control_loading_tv.setText("视频解析错误");
                upHandler.removeCallbacks(upRunable);
                upHandler.removeCallbacks(topAndbottomRunable);
                invokeTopAndBottomLayout(false);
                control_start_btn.setImageResource(R.mipmap.icon_video_play);
                break;
            case PlayerStatus.STATE_COMPLETED:
                //播放结束
                control_loading_layout.setVisibility(GONE);
                control_start_btn.setImageResource(R.mipmap.icon_video_play);
                upHandler.removeCallbacks(upRunable);
                upHandler.removeCallbacks(topAndbottomRunable);
                invokeTopAndBottomLayout(true);
                break;
            case PlayerStatus.STATE_RESTART:
                //播放重置

                break;
            case PlayerStatus.STATE_CHANGE_LINE:
                //切换视频源
                Toast.makeText(getContext(), "正在切换", Toast.LENGTH_SHORT).show();
                upHandler.removeCallbacks(upRunable);
                upHandler.removeCallbacks(topAndbottomRunable);
                break;
            case PlayerStatus.STATE_SEEKTO_START:
                //seekto
                control_loading_layout.setVisibility(VISIBLE);
                control_loading_tv.setText("视频加载中...");
                break;
            case PlayerStatus.STATE_SEEKTO_END:
                //seekto
                control_loading_layout.setVisibility(GONE);
                break;
        }
    }

    /**
     * 播放模式状态改变回调--全屏and正常
     */
    public void onPlayModeChanged(int mCurrentMode) {
        if (mCurrentMode == PlayerStatus.MODE_FULL_SCREEN) {
            //全屏
            control_title_battery.setVisibility(VISIBLE);
            control_full.setImageResource(R.mipmap.iconfont_exit);
            getContext().registerReceiver(mBatterReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
            if (null != linePathMap) {
                control_line.setVisibility(VISIBLE);
                invokeLineShowTv();
            }
        } else if (mCurrentMode == PlayerStatus.MODE_NORMAL) {
            //正常
            control_title_battery.setVisibility(GONE);
            control_full.setImageResource(R.mipmap.iconfont_enter_32);
            getContext().unregisterReceiver(mBatterReceiver);
            control_line.setVisibility(GONE);
        }
    }

    /**
     * 电池状态即电量变化广播接收器
     */
    private BroadcastReceiver mBatterReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS,
                    BatteryManager.BATTERY_STATUS_UNKNOWN);
            if (status == BatteryManager.BATTERY_STATUS_CHARGING) {
                // 充电中
                control_title_battery.setImageResource(R.mipmap.battery_charging);
            } else if (status == BatteryManager.BATTERY_STATUS_FULL) {
                // 充电完成
                control_title_battery.setImageResource(R.mipmap.battery_full);
            } else {
                int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
                int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 0);
                int percentage = (int) (((float) level / scale) * 100);
                if (percentage <= 10) {
                    control_title_battery.setImageResource(R.mipmap.battery_10);
                } else if (percentage <= 20) {
                    control_title_battery.setImageResource(R.mipmap.battery_20);
                } else if (percentage <= 50) {
                    control_title_battery.setImageResource(R.mipmap.battery_50);
                } else if (percentage <= 80) {
                    control_title_battery.setImageResource(R.mipmap.battery_80);
                } else if (percentage <= 100) {
                    control_title_battery.setImageResource(R.mipmap.battery_100);
                }
            }
        }
    };

    /**
     * 多路径显示
     */
    public void onPlayPathSet(Map<String, String> map) {
        this.linePathMap = map;
        if (null == map) {
            control_line.setVisibility(GONE);
        } else {
            linePathDialog = LinePathDialog.builder(getContext(), map, myVideoControlInterface);
            linePathDialog.setOnDismissListener(lineDialogDissClick);
        }
        if (myVideoControlInterface.currModeStatus() == PlayerStatus.MODE_FULL_SCREEN) {
            control_line.setVisibility(VISIBLE);
            invokeLineShowTv();
        } else {
            control_line.setVisibility(GONE);
        }
    }

    private void invokeLineShowTv() {
        if (null != linePathMap) {
            for (String key : linePathMap.keySet()) {
                if (myVideoControlInterface.path().equals(linePathMap.get(key))) {
                    control_line.setText(key);
                }
            }
        }
    }

    private DialogInterface.OnDismissListener lineDialogDissClick = new DialogInterface.OnDismissListener() {
        @Override
        public void onDismiss(DialogInterface dialogInterface) {
            invokeTopAndBottomLayout(true);
            upHandler.postDelayed(topAndbottomRunable, 2500);
        }
    };

    /**
     * 当前播放时间/总时间格式化
     */
    private String getTimeProgressFormat(int currentPosition, int duration) {
        int[] currentPosition_array = getMinuteAndSecond(currentPosition);
        int[] duration_array = getMinuteAndSecond(duration);
        return String.format("%02d:%02d/%02d:%02d", currentPosition_array[0], currentPosition_array[1], duration_array[0], duration_array[1]);
    }

    private int[] getMinuteAndSecond(int mils) {
        mils /= 1000;
        int[] time = new int[2];
        time[0] = mils / 60;
        time[1] = mils % 60;
        return time;
    }

    /**
     * handler更新进度
     */
    private Runnable upRunable = new Runnable() {
        @Override
        public void run() {
            int currentPosition = myVideoControlInterface.getCurrentPosition();
            int duration = myVideoControlInterface.getDuration();
            control_time.setText(getTimeProgressFormat(currentPosition, duration));
            upSeekbar();
            upHandler.postDelayed(upRunable, 1000);
        }
    };

    private void upSeekbar() {
        int currentPosition = myVideoControlInterface.getCurrentPosition();
        int duration = myVideoControlInterface.getDuration();
        int pro = myVideoControlInterface.getBufferPercentage();
        control_seekbar.setProgress((int) (100f * currentPosition / duration));
        control_seekbar.setSecondaryProgress(pro);
    }

    /**
     * 隐藏、显示上下的layout
     */
    private void invokeTopAndBottomLayout(boolean visiable) {
        if (visiable) {
            //显示
            control_title_layout.setVisibility(VISIBLE);
            control_bottom_layout.setVisibility(VISIBLE);
        } else {
            //隐藏
            control_title_layout.setVisibility(GONE);
            control_bottom_layout.setVisibility(GONE);
        }
    }

    private Runnable topAndbottomRunable = new Runnable() {
        @Override
        public void run() {
            if (control_bottom_layout.getVisibility() == VISIBLE && myVideoControlInterface.isPlaying()) {
                invokeTopAndBottomLayout(false);
            }
        }
    };

    /**
     * seekbar拖动事件监听
     */
    @Override
    public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
        long position = (long) (myVideoControlInterface.getDuration() * seekBar.getProgress() / 100f);
        int duration = myVideoControlInterface.getDuration();
        control_time.setText(getTimeProgressFormat((int) position, duration));
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {
        upHandler.removeCallbacks(topAndbottomRunable);
        upHandler.removeCallbacks(upRunable);
    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
        if (myVideoControlInterface.isBufferingPaused() || myVideoControlInterface.isPaused()) {
            myVideoControlInterface.restart(false);
        }
        long position = (long) (myVideoControlInterface.getDuration() * seekBar.getProgress() / 100f);
        myVideoControlInterface.seekTo((int) position);
        if (myVideoControlInterface.isCompleted() && seekBar.getProgress() < 100) {
            myVideoControlInterface.pause();
        }
        upHandler.postDelayed(topAndbottomRunable, 2500);
        upHandler.post(upRunable);
    }

    /**
     * 滑动监听
     */
    @Override
    public boolean onTouch(View view, MotionEvent event) {
        //只有在全屏下可以滑动
        if (myVideoControlInterface.currModeStatus() != PlayerStatus.MODE_FULL_SCREEN) {
            return false;
        }
        //只有在播放、暂停、缓存下可以滑动
        if (myVideoControlInterface.isError()||
                myVideoControlInterface.isCompleted()||
                myVideoControlInterface.isIdle()||
                myVideoControlInterface.isPreparing()||
                myVideoControlInterface.isPrepared()){
            return false;
        }
        float x = event.getX();
        float y = event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                Log.e("ttt", "onTouch: anxia");
                mDownX = x;
                mDownY = y;
                mNeedChangePosition = false;
                mNeedChangeVolume = false;
                mNeedChangeBrightness = false;
                if (positionDialog.isShowing()) {
                    positionDialog.dismiss();
                }
                if (brightnessDialog.isShowing()) {
                    brightnessDialog.dismiss();
                }
                if (volumeDialog.isShowing()) {
                    volumeDialog.dismiss();
                }
                break;
            case MotionEvent.ACTION_MOVE:
                float deltaX = x - mDownX;
                float deltaY = y - mDownY;
                float absDeltaX = Math.abs(deltaX);
                float absDeltaY = Math.abs(deltaY);
                //防止在滑动的时候出现同时改变亮度-进度-音量的情况
                if (!mNeedChangePosition && !mNeedChangeVolume && !mNeedChangeBrightness) {
                    if (absDeltaX >= 80) {
                        //改变进度
                        mNeedChangePosition = true;
                        mGestureDownPosition = myVideoControlInterface.getCurrentPosition();
                        upHandler.removeCallbacks(upRunable);
                        upHandler.removeCallbacks(topAndbottomRunable);
                        invokeTopAndBottomLayout(true);
                        if (!positionDialog.isShowing()) {
                            positionDialog.myshow();
                        }
                    } else if (absDeltaY >= 80) {
                        if (mDownX < getWidth() * 0.5f) {
                            // 左侧改变亮度
                            mNeedChangeBrightness = true;
                            mGestureDownBrightness = ((Activity) getContext()).getWindow().getAttributes().screenBrightness;
                            if (mGestureDownBrightness == -1) {
                                mGestureDownBrightness = 0.5f;
                            }
                            if (!brightnessDialog.isShowing()) {
                                brightnessDialog.myshow();
                            }
                        } else {
                            // 右侧改变声音
                            mNeedChangeVolume = true;
                            mGestureDownVolume = myVideoControlInterface.getVolume();
                            if (!volumeDialog.isShowing()) {
                                volumeDialog.myshow();
                            }
                        }
                    }
                }
                //改变进度
                if (mNeedChangePosition) {
                    long duration = myVideoControlInterface.getDuration();
                    long toPosition = (long) (mGestureDownPosition + duration * deltaX / getWidth());
                    mNewPosition = Math.max(0, Math.min(duration, toPosition));
                    String str_position = getTimeProgressFormat((int) mNewPosition, (int) duration);
                    control_time.setText(str_position);
                    int newPositionProgress = (int) (100f * mNewPosition / duration);
                    control_seekbar.setProgress(newPositionProgress);
                    positionDialog.upDataShow(str_position);
                }
                //改变亮度
                if (mNeedChangeBrightness) {
                    deltaY = -deltaY;
                    float deltaBrightness = deltaY * 3 / getHeight();
                    float newBrightness = mGestureDownBrightness + deltaBrightness;
                    newBrightness = Math.max(0, Math.min(newBrightness, 1));
                    float newBrightnessPercentage = newBrightness;
                    WindowManager.LayoutParams params = ((Activity) getContext()).getWindow().getAttributes();
                    params.screenBrightness = newBrightnessPercentage;
                    ((Activity) getContext()).getWindow().setAttributes(params);
                    int newBrightnessProgress = (int) (100f * newBrightnessPercentage);
                    brightnessDialog.upDataShow(newBrightnessProgress);
                }
                //改变音量
                if (mNeedChangeVolume) {
                    deltaY = -deltaY;
                    int maxVolume = myVideoControlInterface.getMaxVolume();
                    int deltaVolume = (int) (maxVolume * deltaY * 3 / getHeight());
                    int newVolume = mGestureDownVolume + deltaVolume;
                    newVolume = Math.max(0, Math.min(maxVolume, newVolume));
                    myVideoControlInterface.setVolume(newVolume);
                    int newVolumeProgress = (int) (100f * newVolume / maxVolume);
                    volumeDialog.upDataShow(newVolumeProgress);
                }

                break;

            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                if (mNeedChangePosition) {
                    myVideoControlInterface.seekTo((int) mNewPosition);
                    upHandler.post(upRunable);
                    upHandler.post(topAndbottomRunable);
                    if (positionDialog.isShowing()) {
                        positionDialog.dismiss();
                    }
                    return true;
                }
                if (mNeedChangeBrightness) {
                    if (brightnessDialog.isShowing()) {
                        brightnessDialog.dismiss();
                    }
                    return true;
                }
                if (mNeedChangeVolume) {
                    if (volumeDialog.isShowing()) {
                        volumeDialog.dismiss();
                    }
                    return true;
                }
                break;
        }
        return false;
    }

}
